home *** CD-ROM | disk | FTP | other *** search
/ Die Ultimative Software-P…i Collection 1996 & 1997 / Die Ultimative Software-Pakete CD-ROM fur Atari Collection 1996 & 1997.iso / i / internet / software / dlinksr / nicdrv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-21  |  18.5 KB  |  849 lines

  1. /********************************************************************/
  2. /*                                                                    */
  3. /*    Packet driver for D-LINK DE600 ethernet controller                */
  4. /*                                                                    */
  5. /*    Copyleft by P. Mayer, 1993 TU-Vienna IAEE                        */
  6. /*    All rights reserved                                                */
  7. /*                                                                    */
  8. /********************************************************************/
  9.  
  10. #define NOTTVERSION
  11. #define NOIRQVERSION
  12.  
  13. #define LOCKMEM  0x1
  14. #define LOCKALLO 0x2
  15. #define LOCKFREE 0x4
  16. #define LOCKMAIN 0x8
  17. #define LOCKRES  0x10
  18. #define LOCKREC  0x20
  19. #define LOCKNET  0x40
  20.  
  21. #include <stdio.h>
  22. #include <stddef.h>
  23. #include <string.h>
  24. #include <tos.h>
  25. #include <time.h>
  26. #include "nicmem.h"
  27. #include "nicdrv.h"
  28. #include "pktqueue.h"
  29. #include "pktdrv.h"
  30. #include "cookie.h"
  31. #include "inetcust.h"
  32.  
  33. #define noDEBUG
  34. #define noDEBUGINTR
  35. #define noDEBUGPKT
  36. #define NORMAL
  37.  
  38. #define Bconws(x) dpy = x;while(*dpy)(Bconout(2,*dpy++))
  39.  
  40. char str[80];
  41. char *dpy;
  42.  
  43. extern long dclock(void);
  44.  
  45. PKTBUF PPKT[MAXPKT];
  46.  
  47. PKTPOOL PPOOL;
  48.  
  49. extern char nic_locked;
  50. extern procref old_intr;
  51.  
  52. int  retval;
  53. int     term = 0;
  54. int good = 0;
  55. et_hdr        header;
  56. int mode;
  57.  
  58. #define CENBUSY_vectornum 64
  59. #define SPUR_vectornum 24
  60.  
  61. void (*ihandler)(void) = NULL;
  62. extern void dlink_200interrupt(void);
  63. extern void dlink_interrupt(void);
  64. extern void vbl_loop(void);
  65. extern void nic_install(void);
  66. extern long *old200;
  67. extern long disablirq(void);
  68. extern long enablirq(void);
  69. extern long quitirq(void);
  70. int resetNIC(void);  /* reset dlink, init datastructures  */
  71.  
  72. PKTPOOL            *p_free;                  /* queue of free packets */
  73. u_short            freecnt;                  /* number of free packets */
  74.  
  75. procref ext_tab[8] =                    /* subfunction table */
  76. {
  77.   net_reset,
  78.   net_open,
  79.   net_release,
  80.   net_send,
  81.   net_getadr,
  82.   (procref)net_info,
  83.   (procref)net_pktalloc,
  84.   net_pktfree
  85. };
  86.  
  87. PROTOCOL protos[MAXPROTOCOLS];  /* protocols to serve */
  88. int protocols = 0;              /* number of active protocols */
  89.  
  90. et_stat stat;                   /* statistics block */
  91.  
  92. #define NIC_BASE 0xfa0201L
  93.  
  94. typedef unsigned char byte;
  95.  
  96. byte CurTxPage, Mode_RxPg;
  97. int RxPktLen, RxStartAdd, TxStartAdd, CurRxPage, our_type;
  98. byte our_address[6];
  99. int last, LastTxStartAdd;
  100. int ix;
  101.  
  102. #define WRITE        (0x00 << 1)
  103. #define READ        (0x01 << 1)
  104. #define STATUS        (0x02 << 1)
  105. #define COMMAND        (0x03 << 1)
  106. #define NUL_CMD     (0x0c << 1)
  107. #define RX_LEN        (0x05 << 1)
  108. #define TX_ADR        (0x06 << 1)
  109. #define RW_ADR        (0x07 << 1)
  110.  
  111. #define WRITE_STROBE    (0x08 << 1)
  112.  
  113. #define RXEN        (0x08)
  114. #define TXEN        (0x04)
  115. #define LOOPBACK    (0x0c)
  116. #define RX_NONE        (0x00)
  117. #define RX_ALL        (0x01)
  118. #define RX_BP        (0x02)
  119. #define RX_MBP        (0x03)
  120.  
  121. #define RESET        (0x80)
  122. #define STOP_RESET    (0x00)
  123.  
  124. #define RXBUSY        0x80
  125. #define GOOD        0x40
  126. #define RESET_FLAG    0x20
  127. #define T16            0x10
  128. #define TXBUSY        0x08
  129.  
  130. #define BFRSIZ        2048
  131. #define RUNT        60
  132. #define EADDR_LEN    6
  133. #define HA13        0x20
  134. #define PAGE_0        0x00
  135. #define PAGE_1        0x08
  136. #define PAGE_2        0x10
  137. #define PAGE_3        0x18
  138.  
  139. #ifdef TTVERSION
  140. #define delay()     {ix = ix +9;} /* no delay needed for ST */
  141. #else
  142. #define delay()
  143. #endif
  144. #define pause()
  145.  
  146. /* defines for access to DE600 */
  147.  
  148. #define WRITE_SUPER_FAST(value, cmd) \
  149.     x = *(byte*)(base + (int)((((((int)value) << 5) & 0x1e0)) + cmd)); \
  150.     x = *(byte*)(base + (int)((((((int)value) << 1) & 0x1e0) + ((cmd) ^ WRITE_STROBE)))); \
  151.  
  152. #define WRITE_S_FAST(value, cmd) \
  153.     x = *(byte*)(base + (int)((((((int)value) << 5) & 0x1e0)) + cmd)); \
  154.     x = *(byte*)(base + (int)((((((int)value) << 5) & 0x1e0)) + cmd)); \
  155.     x = *(byte*)(base + (int)((((((int)value) << 1) & 0x1e0) + ((cmd) ^ WRITE_STROBE)))); \
  156.     x = *(byte*)(base + (int)((((((int)value) << 1) & 0x1e0) + ((cmd) ^ WRITE_STROBE)))); \
  157.  
  158. #define READ_STAT \
  159.     x = *(byte*)(base + (int)STATUS); \
  160.     y = (*(byte*)(base + (int)NUL_CMD)/* & 0xf0*/)/* ^ 0x80*/; \
  161.  
  162. #define READ_STAT1 \
  163.     x = *(byte*)(base + (int)NUL_CMD); \
  164.     x = *(byte*)(base + (int)STATUS); \
  165.     x = *(byte*)(base + (int)STATUS); \
  166.     delay();\
  167.     y = (*(byte*)(base + (int)NUL_CMD) /*& 0xf0*/) /*^ 0x80*/; \
  168.  
  169. #define READ_STAT2 \
  170.     x = *(byte*)(base + (int)STATUS + 0x200); \
  171. /*    y = *(byte*)(base + (int)STATUS + 0x200); \*/
  172.  
  173. #define READ_SUB_FAST(cmd) \
  174.     x = *(byte*)(base + (int)(cmd)); \
  175.     delay(); \
  176.     x = (*(byte*)(base + (int)(cmd))) /*& 0xf0*/; \
  177.     x >>= 4; \
  178.        y = *(byte*)(base + (int)(cmd + WRITE_STROBE)); \
  179.        delay(); \
  180.      y = (((*(byte*)(base + (cmd | WRITE_STROBE)) /*& 0xf0*/)) | x); \
  181.     /*y ^= 0x88; */\
  182.  
  183. #define READ_FIRST(cmd) \
  184.     x = *(byte*)(base + (int)(cmd)); \
  185.     delay(); \
  186.      x = (((*(byte*)(base + (cmd | WRITE_STROBE)) /*& 0xf0*/))); \
  187.     x >>= 4; \
  188.  
  189. #define READ_LOOP(cmd) \
  190.      y = (((*(byte*)(base + cmd) /*& 0xf0*/)) | x); \
  191.     delay(); \
  192.      y = (((*(byte*)(base + cmd) /*& 0xf0*/)) | x); \
  193. /*    y ^= 0x88;*/ \
  194.      x = (((*(byte*)(base + (cmd | WRITE_STROBE)) /*& 0xf0*/))); \
  195.     delay(); \
  196.      x = (((*(byte*)(base + (cmd | WRITE_STROBE)) /*& 0xf0*/))); \
  197.     x >>= 4; \
  198.  
  199. #define READ_LAST(cmd) \
  200.      y = (((*(byte*)(base + (cmd | WRITE_STROBE)) /*& 0xf0*/)) | x); \
  201.     delay(); \
  202.      y = (((*(byte*)(base + (cmd | WRITE_STROBE)) /*& 0xf0*/)) | x); \
  203. /*    y ^= 0x88; \*/
  204.  
  205. int copyEAD()
  206. {
  207.   register byte *base = (byte*)NIC_BASE;
  208.   register byte x,y;
  209.   int i;
  210.  
  211.   WRITE_SUPER_FAST(0,RW_ADR);
  212.   WRITE_SUPER_FAST(HA13,RW_ADR);
  213.  
  214.   for(i = 0; i < EADDR_LEN;i++) 
  215.   {
  216.     READ_SUB_FAST(READ);
  217.     our_address[i] = y;
  218.   }
  219.   if(   our_address[0] == 0x00 
  220.      && our_address[1] == 0xde 
  221.      && our_address[2] == 0x15)
  222.   {
  223.     our_address[1] = 0x80;
  224.     our_address[2] = 0xc8;
  225.  
  226.     /* our_address[3] &= 0x0f;
  227.        our_address[3] |= 0x70; */
  228.   }
  229.   else
  230.   {
  231.     Cconws("\r\nDE600 no address!!\r\n");
  232.     return -1;
  233.   }
  234.  
  235.   WRITE_SUPER_FAST(0,RW_ADR);
  236.   WRITE_SUPER_FAST(HA13,RW_ADR);
  237.  
  238.   for(i = 0;i < EADDR_LEN;i++) 
  239.   {
  240.     WRITE_SUPER_FAST(our_address[i],WRITE);
  241.   }
  242.   x++;
  243.   return 0;
  244. }
  245.  
  246. /***************************************************
  247.   test for de600 ethernetadapter on cartridge port
  248.  ***************************************************/
  249.  
  250. int Check_DE600()
  251. {
  252.   register byte *base = (byte*)NIC_BASE;
  253.   register byte x,y;
  254.  
  255.   x = *(byte*)(base + NUL_CMD);
  256.   x = *(byte*)(base + NUL_CMD);
  257.   delay();
  258.   WRITE_SUPER_FAST(RESET,COMMAND);
  259.   delay();
  260.   WRITE_SUPER_FAST(STOP_RESET,COMMAND);
  261.   delay();
  262.   READ_STAT1;
  263.   x++;     
  264.   if(y == 0) return 0;
  265.   else
  266.   {
  267.     Cconws("\r\nDE600 not detected!!\r\n");
  268.     return -1;
  269.   }
  270. }
  271.  
  272. int send_packet(byte *p_pkt, int pkt_len)
  273. {
  274.   register byte *base = (byte*)NIC_BASE;
  275.   register byte x,y;
  276.   register int TxStartAdd,val;
  277.   void rcv_pkt(void);
  278.  
  279.   if(pkt_len < RUNT) pkt_len = RUNT;
  280.   pkt_len = (pkt_len+1) & ~1;  /* make sure min. size */
  281.  
  282.   READ_STAT1;
  283.   CurTxPage ^= 0x8;        /* next free buffer */
  284.  
  285.   TxStartAdd = (BFRSIZ - pkt_len) | ((int)CurTxPage << 8);
  286.   WRITE_SUPER_FAST(TxStartAdd & 0xff, RW_ADR);  
  287.   WRITE_SUPER_FAST(TxStartAdd >> 8, RW_ADR);  
  288.  
  289.   while(pkt_len--)
  290.   {
  291.     val = *p_pkt++;
  292.     WRITE_SUPER_FAST(val,WRITE);
  293.   }
  294.   last = ( ( ( (int)(*(p_pkt-1)) << 1) & 0x1e0) + ((WRITE) ^ WRITE_STROBE));
  295. /*
  296.   for(loop_cnt = 0x4000;loop_cnt--;)
  297.   {
  298.     y = (*(byte*)(base + (int)last)) ^ 0x80;
  299.     if((y & TXBUSY) == 0)
  300.     {
  301.      /*Bconws("s");*/
  302.      break;
  303.     }
  304.   }
  305. */
  306.   LastTxStartAdd = TxStartAdd;
  307.   WRITE_SUPER_FAST(TxStartAdd & 0xff, TX_ADR);
  308.   WRITE_SUPER_FAST(TxStartAdd >> 8, TX_ADR);
  309.   WRITE_SUPER_FAST(Mode_RxPg, COMMAND);
  310.   WRITE_SUPER_FAST(Mode_RxPg | TXEN, COMMAND);
  311.   mode = RXEN;
  312.  
  313.   stat.st_sent++;
  314.   READ_STAT2;
  315.   x++;y++;
  316.   return pkt_len;
  317. }
  318.  
  319. int test_mem()
  320. {
  321.   register byte *base = (byte*)NIC_BASE;
  322.   register byte x,y;
  323.   register int i;
  324.  
  325.   nic_locked |= LOCKMEM;
  326.   
  327.   WRITE_SUPER_FAST(0,RW_ADR);
  328.   WRITE_SUPER_FAST(0,RW_ADR);
  329.   for(i = 0;i < 0x800;i++)
  330.   {
  331.     WRITE_SUPER_FAST(i & 0xff,WRITE);
  332.   }
  333.   WRITE_SUPER_FAST(0,RW_ADR);
  334.   WRITE_SUPER_FAST(0,RW_ADR);
  335.   for(i=0;i<0x800;i++)
  336.   {
  337.     READ_SUB_FAST(READ);
  338.     if((i & 0xff) != y)
  339.     {
  340.       Cconws("\r\nDE600 memory test error!!\r\n");
  341.       nic_locked &= ~LOCKMEM;
  342.       return -1;
  343.     }
  344.   }
  345.   x++;
  346.   nic_locked &= ~LOCKMEM;
  347.   return 0;
  348. }
  349.  
  350. int resetNIC(void)
  351. {
  352.   int copyEAD(void);
  353.   int test_mem(void);
  354.   void enable_rcv(void);
  355.   int Check_DE600(void);
  356.  
  357.   CurRxPage = 0x20;
  358.   Mode_RxPg = RX_BP | 0x20;
  359.   CurTxPage = 0;
  360.  
  361.   if(Check_DE600()) return -1;
  362.   if(test_mem()) return -2;
  363.   if(copyEAD()) return -3;
  364.   enable_rcv();
  365.   return 0; 
  366. }
  367.  
  368. void stopNIC(void)
  369. {
  370.   register byte *base = (byte*)NIC_BASE;
  371.   register byte x,y;
  372.  
  373.   READ_STAT1;
  374.   WRITE_SUPER_FAST(Mode_RxPg, COMMAND);
  375.   x++;y++; 
  376. }
  377.  
  378. byte NICstatus()
  379. {
  380.   register byte *base = (byte*)NIC_BASE;
  381.   register byte x,y;
  382.  
  383.   READ_STAT;
  384.   x++;
  385.   return y;
  386. }
  387.  
  388. void enable_rcv()
  389. {
  390.   register byte *base = (byte*)NIC_BASE;
  391.   register byte x,y;
  392.  
  393.   READ_STAT1;
  394.   WRITE_SUPER_FAST(Mode_RxPg, COMMAND);
  395.   WRITE_SUPER_FAST(Mode_RxPg | RXEN, COMMAND);
  396.   mode = RXEN;
  397.   READ_STAT2;
  398.   x++;y++;
  399. }
  400.  
  401. int read_inf(void)
  402. {
  403.   COOKIE *cookie;
  404.  
  405.   cookie = get_cookie(INETCUSTCOOKIE);
  406.   if(!cookie || !cookie->val) return(0);
  407.   return(1);
  408. }
  409.  
  410. long net_info(int len, char *buf)
  411. {
  412.  
  413.   nic_locked |= LOCKNET;
  414.  
  415.   if(buf == (char *)0L) 
  416.   {
  417.     Mode_RxPg = (Mode_RxPg & 0xfc) | len;
  418.     nic_locked &= ~LOCKNET;
  419.     return(0);
  420.   }
  421.   if(buf == (char *)1L) 
  422.   {
  423.     resetNIC();
  424.     nic_locked &= ~LOCKNET;
  425.     return(0);
  426.   }
  427.   if(buf == (char *)2L) 
  428.   {
  429.     nic_locked &= ~LOCKNET;
  430.     return((long)&PPOOL);
  431.   }
  432.   if(buf == (char *)3L) 
  433.   {
  434.     nic_locked &= ~LOCKNET;
  435.     return((long)protos);
  436.   }
  437.   stat.st_free = freecnt;
  438.   memcpy(buf,(char *)&stat,(size_t)len<sizeof(stat)?len:(int)sizeof(stat));
  439.  
  440.   nic_locked &= ~LOCKNET;
  441.   return(len);
  442. }
  443.  
  444. int net_open(int type, int (*handler)(int,char *))
  445. {
  446.   int i,new;
  447.  
  448.   if(!handler) return(EPARAM);
  449.   if(protocols >= MAXPROTOCOLS) return(EPROTAVAIL);
  450.   new = -1;
  451.   nic_locked |= LOCKNET;
  452.   if(!protocols)
  453.   {
  454.     if(net_reset() < 0)
  455.     {
  456.       nic_locked &= ~LOCKNET;
  457.       return(EINIT);
  458.     }
  459.   }
  460.   for(i = 0; i < MAXPROTOCOLS; i++)
  461.   {
  462.     /* protocol already used */
  463.     if(protos[i].type == type)
  464.     {
  465.       nic_locked &= ~LOCKNET;
  466.       return(EPROTUSED);
  467.     }
  468.     if(protos[i].type == ET_UNUSED &&  new<0 ) new = i;  /* find first free entry */
  469.   }
  470.   if(new < 0) new = protocols;
  471.   protocols++;
  472.   protos[new].handler = handler;
  473.   protos[new].recvd = 0;
  474.   protos[new].sent = 0;
  475.   protos[new].type = type;
  476.   nic_locked &= ~LOCKNET;
  477.   return(new);
  478. }
  479.  
  480. int net_release(int type)
  481. {
  482.   int i;
  483.   void stopNIC(void);
  484.  
  485.   if(!protocols) return(EPROTUSED);
  486.   if(type == ET_UNUSED) return(EPROTUSED);
  487.  
  488.   for(i=0; i < MAXPROTOCOLS; i++)
  489.     if(protos[i].type == type) break;
  490.   if(i==MAXPROTOCOLS)
  491.   {
  492.     return(EPROTUSED);
  493.   }
  494.   nic_locked |= LOCKNET;
  495.   protocols--;
  496.   if(!protocols)
  497.   {
  498.     stopNIC();
  499.   }
  500.   protos[i].type = ET_UNUSED;
  501.   protos[i].handler = NULL;
  502.   nic_locked &= ~LOCKNET;
  503.   return(protocols);
  504. }
  505.  
  506. int net_send(int len, char *buf)
  507. {
  508.   void rcv_pkt(void);
  509.   byte NICstatus(void);
  510.   void enable_rcv(void);
  511. #ifdef DEBI
  512.   printf("netsend %lx length %d good = %d mode = %x\n",buf,len,good,mode);
  513. #endif
  514.  
  515.   if(!buf || !len || (buf < (char *)PPKT) || (buf > (char *)&PPOOL)) return(EPARAM);
  516.   if(len < 60) len = 60;
  517.   if(len > (int)sizeof(PACKET)) return(EPKTLEN);
  518.   disablirq();
  519.   nic_locked |= LOCKNET;
  520.   len = send_packet((byte*)buf,len);
  521.  
  522. #ifdef DEBI    
  523.   printf("send done\n");
  524. #endif
  525.   nic_locked &= ~LOCKNET;
  526.   enablirq();
  527.   return(0);
  528. }
  529.  
  530. int    net_getadr(int len, char *buf)
  531. {
  532.   if(len >= (int)sizeof(HADDR))
  533.   {
  534.     buf[0] = our_address[0];
  535.     buf[1] = our_address[1];
  536.     buf[2] = our_address[2];
  537.     buf[3] = our_address[3];
  538.     buf[4] = our_address[4];
  539.     buf[5] = our_address[5];
  540.     return((int)sizeof(HADDR));
  541.   }
  542.   return(0);
  543. }
  544.  
  545. int net_reset(void)
  546. {
  547.   int i,tmp;
  548.  
  549.   disablirq();
  550.   nic_locked |= LOCKRES;
  551.   for(i=0;i<MAXPROTOCOLS;i++)  /* init protocol table */
  552.   {
  553.     protos[i].type = ET_UNUSED;
  554.     protos[i].handler = NULL;
  555.     protos[i].recvd = 0;
  556.     protos[i].sent = 0;
  557.   }
  558.   protocols = 0;
  559.  
  560.   p_free = p_init(MAXPKT,&PPOOL,PPKT);  /* init free packets */
  561.   freecnt = MAXPKT;
  562.  
  563.   tmp = resetNIC();
  564.   nic_locked &= ~LOCKRES;
  565.   enablirq();
  566.   return tmp;
  567. }
  568.  
  569. PKTBUF *net_pktalloc(protocol)
  570. u_short protocol;
  571. {
  572.   PKTBUF * tmp;
  573.  
  574.   if(!p_free) net_reset();
  575.  
  576.   nic_locked |= LOCKALLO;
  577.   if(freecnt <= 1)
  578.   {
  579. Bconws("DLINKDRV: no packet free\r");
  580.     nic_locked &= ~LOCKALLO;
  581.     return(NULL);
  582.   }
  583.   tmp = ap_getpkt(protocol,p_free);
  584.   if(tmp) freecnt--;
  585.   else
  586.   {
  587.    Bconws("DLINKDRV: get packet failed\r");
  588.   }
  589. #ifdef DEBUGPKT
  590.   sprintf(str,"netpktalloc at %lx\r",tmp);
  591.   Bconws(str);
  592. #endif
  593.   nic_locked &= ~LOCKALLO;
  594.   return tmp;
  595. }
  596.  
  597. int net_pktfree(p_pkt)
  598. PKTBUF *p_pkt;
  599. {
  600.   nic_locked |= LOCKFREE;
  601. #ifdef DEBUGPKT
  602.   sprintf(str,"netpktfree at %lx\r",p_pkt);
  603.   Bconws(str);
  604. #endif
  605.   if(!p_free || !p_pkt || (p_pkt < PPKT) || (p_pkt > &PPKT[MAXPKT-1]))
  606.   {
  607.     Bconws("DLINKDRV: free packet out of bounds\r");
  608.     nic_locked &= ~LOCKFREE;
  609.     return(FALSE);
  610.   }
  611.   if(((long)p_pkt - (long)PPKT) % sizeof(PKTBUF))
  612.   {
  613.     Bconws("DLINKDRV: free misaligned packet\r");
  614.     nic_locked &= ~LOCKFREE;
  615.     return(FALSE);
  616.   }
  617.   if(ap_putpkt(p_free,p_pkt))
  618.   {
  619.     freecnt++;
  620.     nic_locked &= ~LOCKFREE;
  621.     return(TRUE);
  622.   }
  623.   Bconws("DLINKDRV: free packet failed\r");
  624.   nic_locked &= ~LOCKFREE;
  625.   return(FALSE);
  626. }
  627.  
  628. void rcv_check(void)
  629. {
  630.  register byte *base = (byte*)NIC_BASE;
  631.  register byte x;
  632.  void rcv_pkt(void);
  633.  
  634.  READ_STAT2;
  635.  if(x & GOOD) rcv_pkt();
  636.  stat.st_intr--;
  637. }
  638.  
  639. /*******************************************************************/
  640. /* read D-LINK function                                            */
  641. /*******************************************************************/
  642.  
  643. void rcv_pkt(void)
  644. {
  645.   register byte *base = (byte*)NIC_BASE;
  646.   register byte x,y,NICstate;
  647.   register int i,ii;
  648.   int       type, RxPktLen;
  649.  
  650.   extern void fastread(void);
  651.   
  652.   et_stat    *et_stat;
  653.   PKTBUF        *pkt;
  654.   byte * pb;
  655.  
  656.   nic_locked |= LOCKREC;
  657.   et_stat = &stat;
  658.   et_stat->st_intr++;
  659.  
  660.   READ_STAT1;
  661.   NICstate = y;
  662.  
  663. do
  664. {
  665.     if(NICstate & GOOD)
  666.     {
  667.       et_stat->st_got++;
  668.  
  669.       READ_SUB_FAST(RX_LEN);
  670.       RxPktLen = y;
  671.       READ_SUB_FAST(RX_LEN);
  672.       RxPktLen += (y << 8);
  673.       RxPktLen -= 4;
  674.  
  675.       Mode_RxPg ^= 0x10;
  676.       WRITE_SUPER_FAST(Mode_RxPg, COMMAND);
  677.       WRITE_SUPER_FAST(Mode_RxPg | RXEN, COMMAND);
  678.       mode = RXEN;
  679.       WRITE_SUPER_FAST(0,RW_ADR);
  680.       WRITE_SUPER_FAST(CurRxPage >> 1,RW_ADR);
  681.       CurRxPage ^= 0x10;
  682.  
  683.       pb = (byte*)&header;
  684.       for(i=0; i < 14;i++)
  685.       {
  686.         READ_SUB_FAST(READ);
  687.         *pb++ = y;
  688.       }
  689.       type = header.et_type;
  690.  
  691.       /*if(header.et_dest[0] != 0xff)*/
  692.       {
  693.           for(i = 0;i < MAXPROTOCOLS; i++)
  694.           {
  695.             if(protos[i].type == type)
  696.             {
  697.               /* must have one packet free */
  698.               if(freecnt > 3 && (pkt = ap_getpkt(type,p_free)) != 0)
  699.               {
  700.                 freecnt--;
  701.                 memcpy((byte*)pkt,(byte*)&header,sizeof(et_hdr));
  702.                 pb = pkt->et_data;
  703.  
  704.                 READ_FIRST(READ);
  705.  
  706.                 ii = RxPktLen - 15;
  707.                 fastread();
  708.                 ii++;
  709.                 
  710.                 READ_LAST(READ);
  711.                 if(protos[i].handler)
  712.                 { 
  713.                  if(protos[i].handler(RxPktLen,(char *)pkt))
  714.                  {
  715.                   et_stat->st_received++;
  716.                   protos[i].recvd++;
  717.                  }
  718.                  else
  719.                  {
  720.                  /* free unused packet */
  721.                   if(ap_putpkt(p_free,pkt)) freecnt++;
  722.                   break;
  723.                  }
  724.                 }
  725.                 else
  726.                 {
  727.                 /* free unused packet */
  728.                   if(ap_putpkt(p_free,pkt)) freecnt++;
  729.                   break;
  730.                 }
  731.               }
  732.               else
  733.               {
  734. /*                Bconws("DLINKDRV: no free packet to recv\r");*/
  735.               }
  736.             }
  737.           }
  738.       }
  739.     }
  740.     else if(!(NICstate & RXBUSY))
  741.     {
  742. /*Bconws("R");    */
  743.       WRITE_SUPER_FAST(Mode_RxPg, COMMAND);
  744.       WRITE_SUPER_FAST(Mode_RxPg | RXEN, COMMAND);
  745.       et_stat->st_missed++;
  746.     }
  747.     if(!(NICstate & TXBUSY))
  748.     {
  749.       WRITE_SUPER_FAST(Mode_RxPg, COMMAND);
  750.       WRITE_SUPER_FAST(Mode_RxPg | RXEN, COMMAND);
  751.     }
  752.     if(NICstate & T16)
  753.     {
  754.       et_stat->st_xmiterr++;
  755.       et_stat->st_collision++;
  756.       WRITE_SUPER_FAST(TxStartAdd & 0xff, TX_ADR);
  757.       WRITE_SUPER_FAST(TxStartAdd >> 8, TX_ADR);
  758.       WRITE_SUPER_FAST(Mode_RxPg, COMMAND);
  759.       WRITE_SUPER_FAST(Mode_RxPg | TXEN, COMMAND);
  760.       WRITE_SUPER_FAST(Mode_RxPg, COMMAND);
  761.       WRITE_SUPER_FAST(Mode_RxPg | RXEN, COMMAND);
  762.     }
  763.     et_stat->st_err = NICstate;
  764.  
  765.   READ_STAT1;
  766.   NICstate = y;
  767. }while(NICstate & GOOD);
  768.   READ_STAT2;
  769.   x++;
  770.   nic_locked &= ~LOCKREC;
  771. }
  772.  
  773. long vbl_install()
  774. {
  775.   long **vblqueue = *(long***)0x456L;
  776.   int vblnum = *(int*)0x454L;
  777.   int i;
  778.  
  779.   for(i=1; i< vblnum;i++) if (*(vblqueue+i) == 0L) break;
  780.  
  781.   if(i< vblnum) 
  782.   {
  783.     *(vblqueue+i) = (long*)vbl_loop;
  784.     return 0;
  785.   }
  786.   else return -1;
  787. }
  788.  
  789. int main()
  790. {
  791.   COOKIE *cookie;
  792.   int (*call)(void);
  793.  
  794.   Supexec(disablirq);
  795. #ifdef IRQVERSION    
  796.   Cconws("\r\nPacket driver V1.1b for Dlink DE600 ");
  797. #else
  798.   Cconws("\r\nPacket driver V1.1bp for Dlink DE600 ");
  799. #endif
  800.   cookie = get_cookie(PKTCOOKIE);
  801.   if(cookie)
  802.   {
  803.     (long)call = ((long *)cookie->val)[NETRESET];
  804.     if(Supexec((long (*)())call) == 0)  /* reset network */
  805.     {
  806.       Cconws("\r\nexisting driver reset\r\n");
  807.       enable_rcv();
  808.       Supexec(enablirq);
  809.     }
  810.     else 
  811.       Cconws("\r\ncould not reset existing driver\r\n");
  812.     return 0;
  813.     
  814.   }
  815.   
  816.   if(!read_inf())
  817.   {
  818.     Cconws("INETCUST not installed !!\r\n");
  819.     return 1;
  820.   }
  821.   else
  822.   {
  823.     ihandler = NULL;
  824.     nic_locked = TRUE;
  825. #ifdef IRQVERSION    
  826.     old_intr = (procref)Setexc(SPUR_vectornum, (void (*)())dlink_interrupt);
  827.     old_intr = (procref)Setexc(CENBUSY_vectornum, (void (*)())dlink_interrupt);
  828.     Supexec((long (*)())nic_install);
  829. #endif
  830.     if(Supexec((long (*)())net_reset) < 0)
  831.     {
  832. #ifdef IRQVERSION    
  833.          Setexc(CENBUSY_vectornum, (void (*)())old_intr);
  834. #endif
  835.       Cconws("\r\nno DE600 detected !!\r\n");
  836.       return 0;
  837.     }
  838.     Supexec(vbl_install);
  839.     enable_rcv();
  840.     ihandler = rcv_pkt;
  841.     nic_locked = 0;
  842.     add_cookie(PKTCOOKIE,(long)ext_tab);
  843.     Cconws("installed\r\n(c) pm FORTec 1993\r\n");
  844.     Ptermres(_PgmSize,0);
  845.   }
  846.   return 0;
  847. }
  848.  
  849.